/* add user code begin Header */
/**
  **************************************************************************
  * @file     main.c
  * @brief    main program
  **************************************************************************
  *                       Copyright notice & Disclaimer
  *
  * The software Board Support Package (BSP) that is made available to
  * download from Artery official website is the copyrighted work of Artery.
  * Artery authorizes customers to use, copy, and distribute the BSP
  * software and its related documentation for the purpose of design and
  * development in conjunction with Artery microcontrollers. Use of the
  * software is governed by this copyright notice and the following disclaimer.
  *
  * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
  * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
  * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
  * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
  * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
  *
  **************************************************************************
  */
/* add user code end Header */

/* Includes ------------------------------------------------------------------*/
#include "at32f421_wk_config.h"
#include "wk_tmr.h"
#include "wk_usart.h"
#include "wk_dma.h"
#include "wk_system.h"

/* private includes ----------------------------------------------------------*/
/* add user code begin private includes */
#include "string.h"
#include "stdio.h"
#include "EV1527.h"
#include "FLASH.h"
/* add user code end private includes */

/* private typedef -----------------------------------------------------------*/
/* add user code begin private typedef */
volatile uint8_t usart1_tx_dma_status = 0;
volatile uint8_t usart1_rx_dma_status = 0;

uint8_t usart1_rx_buffer[DMA1_CHANNEL3_BUFFER_SIZE];
uint16_t g_ulCaptureBuffer[DMA1_CHANNEL4_BUFFER_SIZE];

volatile uint16_t usart1_rx_buffer_size = 0;

volatile uint8_t g_ucDataReady = 0;                        // 数据就绪标志
volatile uint32_t g_ulChipID = 0;                          // 解码后的芯片ID
volatile uint8_t g_ucKeyCode = 0;                          // 解码后的按键码

#define TEST_PAGE            0           // 测试使用的Flash页
#define TEST_DATA_LEN        10          // 测试数据长度（半字数）

// 测试数据
uint16_t testDataWrite[TEST_DATA_LEN] = {0x2233, 0x5678, 0x9ABC, 0xDEF0, 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6667};
uint16_t testDataRead[TEST_DATA_LEN] = {0}; // 读取的数据

/* 传感器数据结构体 */
#pragma pack(push, 1)
typedef struct {
    uint32_t id;
    char     name[20];
    float    temperature;
    uint8_t  status;
    uint16_t checksum;
} SensorData;
#pragma pack(pop)


/* add user code end private typedef */

/* private define ------------------------------------------------------------*/
/* add user code begin private define */

/* add user code end private define */

/* private macro -------------------------------------------------------------*/
/* add user code begin private macro */

/* add user code end private macro */

/* private variables ---------------------------------------------------------*/
/* add user code begin private variables */

/* add user code end private variables */

/* private function prototypes --------------------------------------------*/
/* add user code begin function prototypes */

/* add user code end function prototypes */

/* private user code ---------------------------------------------------------*/
/* add user code begin 0 */
int fputc(int ch, FILE *p)
{
  usart_data_transmit(USART1, (uint8_t)ch);
  while (usart_flag_get(USART1, USART_TDC_FLAG) == RESET)
    ;
  ch = usart_data_receive(USART1);
  return ch;
}

void usart_send(usart_type *usart_x, uint8_t *data, uint16_t len)
{
  while (len)
  {
    while (usart_flag_get(USART1, USART_TDBE_FLAG) == RESET)
      ;
    usart_x->dt = (*data & 0x01FF);
    len--;
    data++;
  }
}

void usart1_dma_send(uint8_t *data, uint16_t len)
{
  while (dma_flag_get(DMA1_FDT2_FLAG) == SET)
    ; // 等待DMA传输完成
  dma_channel_enable(DMA1_CHANNEL2, FALSE);
  wk_dma_channel_config(DMA1_CHANNEL2,
                        (uint32_t)&USART1->dt,
                        (uint32_t)data,
                        len); // 修改为实际字符串长度
  dma_channel_enable(DMA1_CHANNEL2, TRUE);
  
  while (usart_flag_get(USART1, USART_TDC_FLAG) == SET)
    ; // 等待发送完成
  while (usart1_tx_dma_status == 0)
    ; // 等待DMA传输完成
  usart1_tx_dma_status = 0;
}

/* 计算校验和 */
uint16_t CalculateChecksum(void* data, uint16_t size)
{
    uint16_t checksum = 0;
    uint8_t *p = (uint8_t*)data;

    for (uint16_t i = 0; i < size - sizeof(uint16_t); i++) // 排除checksum字段
    {
        checksum += p[i];
    }
    return checksum;
}

/* add user code end 0 */

/**
  * @brief main function.
  * @param  none
  * @retval none
  */
int main(void)
{
  /* add user code begin 1 */

  /* add user code end 1 */

  /* system clock config. */
  wk_system_clock_config();

  /* config periph clock. */
  wk_periph_clock_config();

  /* nvic config. */
  wk_nvic_config();

  /* timebase config. */
  wk_timebase_init();

  /* init dma1 channel2 */
  wk_dma1_channel2_init();
  /* config dma channel transfer parameter */
  /* user need to modify define values DMAx_CHANNELy_XXX_BASE_ADDR and DMAx_CHANNELy_BUFFER_SIZE in at32xxx_wk_config.h */
  wk_dma_channel_config(DMA1_CHANNEL2, 
                        (uint32_t)&USART1->dt, 
                        DMA1_CHANNEL2_MEMORY_BASE_ADDR, 
                        DMA1_CHANNEL2_BUFFER_SIZE);
  dma_channel_enable(DMA1_CHANNEL2, TRUE);

  /* init dma1 channel3 */
  wk_dma1_channel3_init();
  /* config dma channel transfer parameter */
  /* user need to modify define values DMAx_CHANNELy_XXX_BASE_ADDR and DMAx_CHANNELy_BUFFER_SIZE in at32xxx_wk_config.h */
  wk_dma_channel_config(DMA1_CHANNEL3, 
                        (uint32_t)&USART1->dt, 
                        DMA1_CHANNEL3_MEMORY_BASE_ADDR, 
                        DMA1_CHANNEL3_BUFFER_SIZE);
  dma_channel_enable(DMA1_CHANNEL3, TRUE);

  /* init dma1 channel4 */
  wk_dma1_channel4_init();
  /* config dma channel transfer parameter */
  /* user need to modify define values DMAx_CHANNELy_XXX_BASE_ADDR and DMAx_CHANNELy_BUFFER_SIZE in at32xxx_wk_config.h */
  wk_dma_channel_config(DMA1_CHANNEL4, 
                        (uint32_t)&TMR3->c1dt, 
                        DMA1_CHANNEL4_MEMORY_BASE_ADDR, 
                        DMA1_CHANNEL4_BUFFER_SIZE);
  dma_channel_enable(DMA1_CHANNEL4, TRUE);

  /* init usart1 function. */
  wk_usart1_init();

  /* init tmr1 function. */
  wk_tmr1_init();

  /* init tmr3 function. */
  wk_tmr3_init();

  /* add user code begin 2 */
  /* enable transfer full data interrupt */
  dma_interrupt_enable(DMA1_CHANNEL2, DMA_FDT_INT, TRUE);
  dma_interrupt_enable(DMA1_CHANNEL4, DMA_FDT_INT, TRUE);

  /* dma1 channel2 interrupt nvic init */
  nvic_irq_enable(DMA1_Channel3_2_IRQn, 0, 0);
  nvic_irq_enable(DMA1_Channel5_4_IRQn, 0, 0);
  /* enable transfer full data interrupt */
  dma_interrupt_enable(DMA1_CHANNEL3, DMA_FDT_INT, TRUE);

  /* dma1 channel3 interrupt nvic init */
  nvic_irq_enable(DMA1_Channel3_2_IRQn, 0, 0);
  dma_channel_enable(DMA1_CHANNEL4, TRUE); // 使能 DMA1 的通道 4

  usart_interrupt_enable(USART1, USART_IDLE_INT, TRUE);
  nvic_irq_enable(USART1_IRQn, 0, 0);
  usart_enable(USART1, TRUE);

  //tmr_interrupt_enable(TMR3, TMR_C1_INT, TRUE);  // 使能 TMR3 的通道 1 的中断
  //tmr_interrupt_enable(TMR3, TMR_C2_INT, TRUE);  // 使能 TMR3 的通道 1 的中断
  tmr_output_enable(TMR1, TRUE); // 使能 TMR11 的输出
  tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_1, 100); // 设置 TMR11 的通道 1 的比较值
  tmr_counter_enable(TMR1, TRUE); // 启动 TMR11 的计数器

  //__disable_irq(); // 禁用全局中断


  //恢复中断
 // __enable_irq(); // 启用全局中断
  /* 定义并填充测试数据 */
  SensorData sensor = { 
      .id = 2233, 
      .name = "TempSensor03", 
      .temperature = 36.5, 
      .status = 7 
  };
  sensor.checksum = CalculateChecksum(&sensor, sizeof(SensorData)); // 计算校验和 

  /* 写入 Flash（支持磨损均衡）*/
  flash_status_type status = EEPROM_WriteStruct(0, &sensor, sizeof(SensorData), 1);
  if (status == FLASH_OPERATE_DONE)
  {
      printf("写入成功!\n");
  }
  else
  {
      printf("写入失败, 错误码: %d\n", status);
  }

  /* 读取 Flash */
  SensorData readSensor;
  EEPROM_ReadStruct(0, &readSensor, sizeof(SensorData));

  /* 校验数据 */
  if (readSensor.checksum == CalculateChecksum(&readSensor, sizeof(SensorData)))
  {
      printf("读取成功!\n");
      printf("ID: %d\n", readSensor.id);
      printf("Name: %s\n", readSensor.name);
      printf("Temperature: %.2f\n", readSensor.temperature);
      printf("Status: %d\n", readSensor.status);
  }
  else
  {
      printf("读取失败, 数据校验错误!\n");
  }

  /* add user code end 2 */

  while(1)
  {
    /* add user code begin 3 */
    if (usart1_rx_dma_status == 1)
    {
      usart1_rx_dma_status = 0;
      usart1_dma_send((uint8_t *)usart1_rx_buffer, usart1_rx_buffer_size);
    }

    if (g_ucDataReady) {
      EV1527_ProcessData();
      // 示例：通过串口输出解码结果
      //printf("芯片ID: %lu, 按键码: %u\n", g_ulChipID, g_ucKeyCode);
      }
      wk_delay_ms(10);  // 低功耗优化，减少 CPU 占用率

    /* add user code end 3 */
  }
}

  /* add user code begin 4 */

  /* add user code end 4 */
